package com.tkwayne.ftpclient.core;

import com.tkwayne.ftpclient.config.FTPAbandonedConfig;
import com.tkwayne.ftpclient.config.FtpPoolConfig;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/**
 * FTPClientFactory
 * create Object by FTPClientFactory
 * @author wayne
 * @description
 * @date 2019/7/20 16:43
 */
public class FTPClientFactory extends BasePooledObjectFactory<FTPClient> {

    private static Logger logger = LoggerFactory.getLogger(FTPClientFactory.class);

    private FtpPoolConfig ftpPoolConfig;

    private FTPAbandonedConfig ftpAbandonedConfig;

	public FtpPoolConfig getFtpPoolConfig() {
		return ftpPoolConfig;
	}

	public void setFtpPoolConfig(FtpPoolConfig ftpPoolConfig) {
		this.ftpPoolConfig = ftpPoolConfig;
	}

    public FTPAbandonedConfig getFtpAbandonedConfig() {
        return ftpAbandonedConfig;
    }

    public void setFtpAbandonedConfig(FTPAbandonedConfig ftpAbandonedConfig) {
        this.ftpAbandonedConfig = ftpAbandonedConfig;
    }

    /**
     * 新建对象
     */
    @Override
    public FTPClient create() throws Exception {
        FTPClient ftpClient = new FTPClient();
        ftpClient.setConnectTimeout(ftpPoolConfig.getConnectTimeOut());
        try {
        	logger.info("connect to FTP Server :{}",ftpPoolConfig.getHost()+ftpPoolConfig.getPort());
        	ftpClient.connect(ftpPoolConfig.getHost(), ftpPoolConfig.getPort());
            int reply = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftpClient.disconnect();
                throw new Exception("FTP Server access denied userName : "+ ftpPoolConfig.getUserName() + ", password : "+ ftpPoolConfig.getPassword());
            }
            boolean result = ftpClient.login(ftpPoolConfig.getUserName(),ftpPoolConfig.getPassword());
            if (!result) {
                throw new Exception("FTP Server login fail userName : "+ ftpPoolConfig.getUserName() + ", password : " + ftpPoolConfig.getPassword());
            }
			ftpClient.setControlEncoding(ftpPoolConfig.getControlEncoding());
			ftpClient.setBufferSize(ftpPoolConfig.getBufferSize());
			ftpClient.setFileType(ftpPoolConfig.getFileType());
			ftpClient.setDataTimeout(ftpPoolConfig.getDataTimeout());
			ftpClient.setUseEPSVwithIPv4(ftpPoolConfig.isUseEPSVWithIPv4());
			if(ftpPoolConfig.isPassiveMode()){
				logger.info("FTP Server into passiveMode");
				ftpClient.enterLocalPassiveMode();
			}
        } catch (Exception e) {
            throw e;
        }
        return ftpClient;
    }

    @Override
    public PooledObject<FTPClient> wrap(FTPClient ftpClient) {
        return new DefaultPooledObject<FTPClient>(ftpClient);
    }

    /**
     * 销毁对象
     */
    @Override
    public void destroyObject(PooledObject<FTPClient> p) throws Exception {
        FTPClient ftpClient = p.getObject();
        ftpClient.logout();
        super.destroyObject(p);
    }

    @Override
    public boolean validateObject(PooledObject<FTPClient> p) {
        FTPClient ftpClient = p.getObject();
        boolean flag;
        try {
            flag = ftpClient.sendNoOp();
            logger.info("activeObject result: {}",flag);
            return flag;
        } catch (IOException e) {
            logger.error("activeObject error");
            return false;
        }
    }
}